﻿using Kenly.DBFramework.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data;
using System;
using Kenly.DBFramework.Gateway;
using System.Collections.Generic;
using System.Collections;

using Kenly.UTAssist;
using Kenly.DBFramework.TestModel.HumanResources;

namespace Kenly.DBFramework.Tests
{


    /// <summary>
    ///这是 EntityMapperTest 的测试类，旨在
    ///包含所有 EntityMapperTest 单元测试
    ///</summary>
    [TestClass()]
    public class EntityMapperGenericTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///获取或设置测试上下文，上下文提供
        ///有关当前测试运行及其功能的信息。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region 附加测试属性
        // 
        //编写测试时，还可使用以下属性:
        //
        //使用 ClassInitialize 在运行类中的第一个测试前先运行代码
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //使用 ClassCleanup 在运行完类中的所有测试后再运行代码
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //使用 TestInitialize 在运行每个测试前先运行代码
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //使用 TestCleanup 在运行完每个测试后运行代码
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        //[TestMethod()]
        //public void InvokeAllWithNullTest()
        //{
        //    var tester = new MethodTester(typeof(EntityMapper<Student>));

        //    tester.InvokeAllWithNull();
        //}

        /// <summary>
        ///ToTable 的测试
        ///</summary>
        [TestMethod()]
        public void ToTableAdaptedTest()
        {
            List<Student> entities = EntityMapperHelper.CreateGenericEntities();

            //DataTable table = EntityMapper<Student>.ToTable(entities);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "ToTable");

            testcase.Execute<DataTable>(p => ValidateAdaptedDataTable(p), entities);

            object[] args = { null };
            testcase.Execute<DataTable>(p => p.Rows.Count == 0, args);

            testcase.Execute<DataTable>(p => p.Rows.Count == 0, new List<Student>());

            entities = new List<Student>();
            entities.Add(null);
            testcase.Execute<DataTable>(p => p.Rows.Count == 0, entities);
        }

        private static bool ValidateAdaptedDataTable(DataTable table)
        {
            Type entityType = EntityMapperHelper.GetEntityType();

            if (table.TableName != entityType.Name)
            {
                return false;
            }

            if (!table.Columns.Contains("StudentID"))
            {
                return false;
            }

            if (!table.Columns.Contains("NationalIDNumber"))
            {
                return false;
            }

            return true;
        }


        /// <summary>
        ///ToTable 的测试
        ///</summary>
        [TestMethod()]
        public void ToTableTest()
        {
            bool isAdapted = false;
            List<Student> entities = EntityMapperHelper.CreateGenericEntities();

            //DataTable table = EntityMapper<Student>.ToTable(entities, isAdapted);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "ToTable");

            testcase.Execute<DataTable>(p => ValidateDataTable(p), entities, isAdapted);

            testcase.Execute<DataTable>(p => p.Rows.Count == 0, null, isAdapted);
            testcase.Execute<DataTable>(p => p.Rows.Count == 0, new List<Student>(), isAdapted);

            entities = new List<Student>();
            entities.Add(null);
            testcase.Execute<DataTable>(p => p.Rows.Count == 0, entities, isAdapted);
        }

        private static bool ValidateDataTable(DataTable table)
        {
            Type entityType = EntityMapperHelper.GetEntityType();

            if (table.TableName != entityType.Name)
            {
                return false;
            }

            if (!table.Columns.Contains(Student.StudentIDColumn))
            {
                return false;
            }

            if (!table.Columns.Contains(Student.NationalIDNumberColumn))
            {
                return false;
            }

            return true;
        }

        /// <summary>
        ///ToPropertyName 的测试
        ///</summary>
        [TestMethod()]
        public void ToPropertyNameTest()
        {
            //string actual = EntityMapper<Student>.ToPropertyName(columnName);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "ToPropertyName");

            testcase.Execute<string>(p => p == "StudentID", Student.StudentIDColumn);

            testcase.Execute<string>(p => p == null, string.Empty);
            testcase.Execute<string>(p => p == null, new object[] { null });

        }

        /// <summary>
        ///ToColumnName 的测试
        ///</summary>
        [TestMethod()]
        public void ToColumnNameTest()
        {
            //string actual = EntityMapper<Student>.ToColumnName(propertyName);

            string propertyName = "StudentID";

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "ToColumnName");

            testcase.Execute<string>(p => p == Student.StudentIDColumn, propertyName);

            testcase.Execute<string>(p => p == null, string.Empty);
            testcase.Execute<string>(p => p == null, new object[] { null });
        }

        /// <summary>
        ///ToEntity 的测试
        ///</summary>
        [TestMethod()]
        public void ToEntityTest()
        {
            //DataRow adaptedRow = null; 
            //Type entityType = null; 
            //object actual = EntityMapper<Student>.ToEntity(adaptedRow);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "ToEntity");
            DataRow adaptedRow = EntityMapperHelper.CreateAdaptedDataRow();

            testcase.Execute<Student>(p => p.StudentID == 100, adaptedRow);

            testcase.Execute<Student>(p => p.StudentID == 0, new object[] { null });

        }

        /// <summary>
        ///ToEntities 的测试
        ///</summary>
        [TestMethod()]
        public void ToEntitiesFromDataRowsTest()
        {
            //DataRowCollection adaptedRows = null;
            //Type entityType = null;
            //List<Student> actual = EntityMapper<Student>.ToEntities(adaptedRows);

            DataTable table = EntityMapperHelper.CreateAdaptedTable();
            ValidateToEntitiesFromDataRows(table);

        }

        private static void ValidateToEntitiesFromDataRows(DataTable table)
        {
            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "ToEntities");
            DataRowCollection adaptedRows = table.Rows;

            testcase.Execute<List<Student>>(p => p.Count == adaptedRows.Count, adaptedRows);
            testcase.Execute<List<Student>>(p => p[0].StudentID == 100, adaptedRows);

            adaptedRows = (new DataTable()).Rows;
            testcase.Execute<List<Student>>(p => p.Count == 0, adaptedRows);

            testcase.Execute<List<Student>>(p => p.Count == 0, new object[] { null });
        }

        /// <summary>
        ///ToEntities 的测试
        ///</summary>
        [TestMethod()]
        public void ToEntitiesTest()
        {
            //DataTable table = null; 
            //Type entityType = null; 
            //List<Student> actual = EntityMapper<Student>.ToEntities(table);

            DataTable table = EntityMapperHelper.CreateAdaptedTable();
            ValidateToEntities(table);
        }

        private static void ValidateToEntities(DataTable table)
        {
            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "ToEntities");

            testcase.Execute<List<Student>>(p => p.Count == table.Rows.Count, table);
            testcase.Execute<List<Student>>(p => p[0].StudentID == 100, table);

            testcase.Execute<List<Student>>(p => p.Count == 0, new DataTable());
            testcase.Execute<List<Student>>(p => p.Count == 0, new object[] { null });
        }

        /// <summary>
        ///CreateTable 的测试
        ///</summary>
        [TestMethod()]
        public void CreateAdaptedTableTest()
        {
            //DataTable actual = EntityMapper<Student>.CreateTable();

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "CreateTable");
            testcase.Execute<DataTable>(p => IsFullAdapted(p));
        }

        /// <summary>
        ///CreateTable 的测试
        ///</summary>
        [TestMethod()]
        public void CreateTableTest()
        {
            bool isAdapted = false;
            //DataTable actual = EntityMapper<Student>.CreateTable(isAdapted);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "CreateTable");

            testcase.Execute<DataTable>(p => IsAdaptedFullToDatabase(p), isAdapted);
        }

        /// <summary>
        ///CreateGenericEntities 的测试
        ///</summary>
        [TestMethod()]
        public void CreateEntitiesTest()
        {
            //List<Student> actual = EntityMapper<Student>.CreateEntities(count);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "CreateEntities");
            int count = 2;

            testcase.Execute<List<Student>>(p => p.Count == count, count);

            testcase.Execute<List<Student>>(p => p.Count==0, 0);
            testcase.Execute<List<Student>>(p => p.Count==0, -1);
        }

        /// <summary>
        ///CanCopyToEntity 的测试
        ///</summary>
        [TestMethod()]
        public void CanCopyToEntityTest()
        {
            Student entity = new Student();
            DataRow row = EntityMapperHelper.CreateAdaptedDataRow();

            //EntityMapper<Student>.CanCopyToEntity(entity, row);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "CanCopyToEntity");

            testcase.Execute<bool>(p => p == true, entity, row);

            testcase.Execute<bool>(p => p == false, null, row);
            testcase.Execute<bool>(p => p == false, entity, null);
        }


        /// <summary>
        ///CopyToEntity 的测试
        ///</summary>
        [TestMethod()]
        public void CopyToEntityTest()
        {
            Student entity = EntityMapperHelper.CreateEmptyEntity();
            DataRow row = EntityMapperHelper.CreateAdaptedDataRow();

            //EntityMapper<Student>.CopyToEntity(entity, row);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "CopyToEntity");

            testcase.Execute(entity, row);
            testcase.AssertResult<Student>(p => p.StudentID == 100, entity);

            testcase.Execute(entity, null);
            testcase.Execute(null, row);
            testcase.Execute(null, null);
        }

        /// <summary>
        ///CopyToEntities 的测试
        ///</summary>
        [TestMethod()]
        public void CopyToEntitiesTest()
        {
            List<Student> entities = EntityMapperHelper.CreateGenericEmptyEntities();

            DataTable adaptedTable = EntityMapperHelper.CreateAdaptedTable();
            //EntityMapper<Student>.CopyToEntities(entities, adaptedTable);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "CopyToEntities");

            testcase.Execute(entities, adaptedTable);
            testcase.AssertResult<List<Student>>(p => p.Count == entities.Count, entities);
            testcase.AssertResult<List<Student>>(p => p[0].StudentID == 100 && p[1].StudentID == 101, entities);

            testcase.Execute(null, adaptedTable);
            testcase.Execute(entities, null);
            testcase.Execute(null, null);
        }

        /// <summary>
        ///CopyToEntities 的测试
        ///</summary>
        [TestMethod()]
        public void CopyToEntitiesFromAdaptedRowsTest()
        {
            List<Student> entities = EntityMapperHelper.CreateGenericEmptyEntities();
            DataRowCollection adaptedRows = EntityMapperHelper.CreateAdaptedTable().Rows;
            //EntityMapper<Student>.CopyToEntities(entities, adaptedRows);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "CopyToEntities");

            testcase.Execute(entities, adaptedRows);
            testcase.AssertResult<List<Student>>(p => p.Count == entities.Count, entities);
            testcase.AssertResult<List<Student>>(p => p[0].StudentID == 100 && p[1].StudentID == 101, entities);

            testcase.Execute(entities, null);
            testcase.Execute(null, adaptedRows);
            testcase.Execute(null, null);
        }

        private static bool IsFullAdapted(DataTable table)
        {
            return table.TableName == "Student" &&
                table.Columns.Contains("StudentID") &&
                table.Columns.Contains("NationalIDNumber");
        }

        /// <summary>
        ///AdaptToEntity 的测试
        ///</summary>
        [TestMethod()]
        public void AdaptToEntityTest()
        {
            DataTable rawTable = EntityMapperHelper.CreateRawTable();
            //EntityMapper<Student>.AdaptToEntity(rawTable);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "AdaptToEntity");

            testcase.Execute(rawTable);
            testcase.AssertResult<DataTable>(p => IsFullAdapted(p), rawTable);

            testcase.Execute(new object[] { null });
        }

        /// <summary>
        ///AdaptToDatabase 的测试
        ///</summary>
        [TestMethod()]
        public void AdaptToDatabaseTest()
        {
            DataTable adaptedTable = EntityMapperHelper.CreateAdaptedTable();
            //EntityMapper<Student>.AdaptToDatabase(adaptedTable);

            TestCase testcase = new TestCase(typeof(EntityMapper<Student>), "AdaptToDatabase");

            testcase.Execute(adaptedTable);
            testcase.AssertResult<DataTable>(p => IsAdaptedFullToDatabase(p), adaptedTable);

            testcase.Execute(new object[] { null });
        }

        private static bool IsAdaptedFullToDatabase(DataTable table)
        {
            return table.TableName == Student.TableName &&
                table.Columns.Contains(Student.StudentIDColumn) &&
                table.Columns.Contains(Student.NationalIDNumberColumn);
        }


    }
}
